#include "thread_pool/thread_pool.h"

#include <iostream>

ThreadPool::ThreadPool(const int threadNums)
{
    for (int i = 0; i < threadNums; i++)
    {
        threads.emplace_back(&ThreadPool::threadFun, this);
    }
}

ThreadPool::~ThreadPool()
{
    stop.store(true);
    conditions.notify_all();
    for (int i = 0; i < threads.size(); i++)
    {
        threads[i].join();
    }

    std::cout << "~ThreadPool\n";
}

void ThreadPool::threadFun()
{
    while (true)
    {
        std::function<void()> task;
        {
            std::unique_lock<std::mutex> lock(mtx);
            conditions.wait(lock, [this]() { return !tasks.empty() || stop.load(); });

            // 必须加这个校验，否则析构函数设置stop，会导致这里队列没清空而退出
            if (tasks.empty() && stop.load())
                return;
            task = std::move(tasks.front());
            tasks.pop();
        }

        task();
    }
}

void ThreadPool::addTask(std::function<void()> task)
{
    std::unique_lock<std::mutex> lock(mtx);

    tasks.push(task);

    conditions.notify_one();
}
